package org.etherframework.tests.features.command
{
	import org.etherframework.common.command.ICommands;
	import org.etherframework.core.IModule;
	import org.etherframework.dependency.IDependencies;
	import org.etherframework.tests.features.command.commands.GestureCommand;
	import org.etherframework.tests.features.command.commands.MyController;
	import org.etherframework.tests.features.command.commands.UpdateItemCommand;
	import org.etherframework.tests.features.command.events.UpdateItemEvent;
	import org.etherframework.tests.features.command.models.Item;
	import org.etherframework.tests.utils.TestUtility;
	import org.hamcrest.assertThat;

	public class when_using_gesture_command
	{
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _module:IModule;
		private static var _g:ICommands;
		private static var _d:IDependencies;
		private static var _dispatchedEvent:UpdateItemEvent;
		private static var _locator:MyController;
		private static var _item1:Item;
		private static var _item2:Item;
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			_module = _testUtility.createModule();
			_g = _module.commands;
			_d = _module.dependencies;
			
			_d.addClass(UpdateItemCommand);
			_d.addSingleton(MyController);
			// UpdateItemCommand is a universal command that can be triggered 
			// standalone (via locator) and by event.
			_g.map(UpdateItemEvent.UPDATE_ITEM, UpdateItemCommand);
			// GestureCommand is for event triggering due to event passed to its constructor.
			_g.map(UpdateItemEvent.UPDATE_ITEM, GestureCommand);
			
			_item1 = new Item();
			_item2 = new Item();
			UpdateItemCommand.executed = new Vector.<UpdateItemCommand>();
			GestureCommand.executed = new Vector.<GestureCommand>();
			_locator = _module.ether.dependencies.getInstance(MyController) as MyController;
			_dispatchedEvent = new UpdateItemEvent(UpdateItemEvent.UPDATE_ITEM, _item1);
			
			// The same command can be triggered by event or manually via command 
			// locator without a need of passing event to constructor.
			_module.ether.dispatch(_dispatchedEvent);
			_locator.getUpdateItemCommand(_item2).execute();
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			_testUtility.dispose();
		}
		
		[Test(order=1)]
		public function it_should_execute_commands():void
		{
			assertThat(UpdateItemCommand.executed[0].wasExecutedWithItem, _item1);
			assertThat(UpdateItemCommand.executed[1].wasExecutedWithItem, _item2);
			assertThat(GestureCommand.executed[0].wasExecutedWithItem, _item1);
		}
	}
}